package com.xbongbong.paas.toolbox.util;

import com.xbongbong.paas.constant.TimeConstant;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * @author: wufeng
 * @date: 2018/11/15 14:15
 * @desrcption: 获取每天、昨天、本周、上周、本月、上月的时间戳
 */
public class GetTimeInMillisUtil {
    /**
     * 获得当天0点时间
     * @return
     */

    public static int getTimesMorning(){

        Calendar cal = Calendar.getInstance();

        cal.set(Calendar.HOUR_OF_DAY, 0);

        cal.set(Calendar.SECOND, 0);

        cal.set(Calendar.MINUTE, 0);

        cal.set(Calendar.MILLISECOND, 0);

        return (int) (cal.getTimeInMillis()/1000);

    }

    /**
     * 获得当天24点时间
     * @return
     */
    public static int getTimesNight(){
        Calendar cal = Calendar.getInstance();

        cal.set(Calendar.HOUR_OF_DAY, 24);

        cal.set(Calendar.SECOND, 0);

        cal.set(Calendar.MINUTE, 0);

        cal.set(Calendar.MILLISECOND, 0);

        return (int) (cal.getTimeInMillis()/1000);
    }

    /**
     * 获取昨天的开始时间
     * @return
     */
    public static Date getBeginDayOfYesterday() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayBegin());
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    /**
     * 获取昨天的结束时间
     * @return
     */
    public static Date getEndDayOfYesterday() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getDayEnd());
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    /**
     *  获取当天的开始时间
     * @return
     */
    public static java.util.Date getDayBegin() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     *  获取当天的结束时间
     * @return
     */
    public static java.util.Date getDayEnd() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }

    /**
     * 获得本周一0点时间
     * @return
     */
    public static int getTimesWeekMorning(){

        Calendar cal = Calendar.getInstance();

        cal.set(cal.get(Calendar.YEAR),cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0,0);

        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

        return (int) (cal.getTimeInMillis()/1000);

    }

    /**
     * 获得本周日24点时间
     * @return
     */
    public static int getTimesWeekNight(){

        Calendar cal = Calendar.getInstance();

        cal.set(cal.get(Calendar.YEAR),cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0,0);

        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

        return (int) ((cal.getTime().getTime()+ (7 * 24 * 60 * 60 * 1000))/1000);

    }

    /**
     * 获得本月第一天0点时间
     * @return
     */

    public static int getTimesMonthMorning(){

        Calendar cal = Calendar.getInstance();

        cal.set(cal.get(Calendar.YEAR),cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0,0);

        cal.set(Calendar.DAY_OF_MONTH,cal.getActualMinimum(Calendar.DAY_OF_MONTH));

        return (int) (cal.getTimeInMillis()/1000);

    }

    /**
     * 获取上个月的起始时间
     * @return
     */
    public static Date getBeginDayOfLastWeek() {
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == 1) {
            dayOfWeek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayOfWeek - 7);
        return getDayStartTime(cal.getTime());
    }

    /**
     *  获取上周的结束时间
     * @return
     */
    public static Date getEndDayOfLastWeek() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfLastWeek());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        return getDayEndTime(weekEndSta);
    }

    /**
     * 获取某个日期的开始时间
     * @param d
     * @return
     */
    public static Timestamp getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d){
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 获取某个日期的结束时间
     * @param d
     * @return
     */
    public static Timestamp getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d){
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 获得本月最后一天24点时间
     */

    public static int getTimesMonthNight(){

        Calendar cal = Calendar.getInstance();

        cal.set(cal.get(Calendar.YEAR),cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0,0);

        cal.set(Calendar.DAY_OF_MONTH,cal.getActualMaximum(Calendar.DAY_OF_MONTH));

        cal.set(Calendar.HOUR_OF_DAY, 24);

        return (int) (cal.getTimeInMillis()/1000);
    }

    /**
     *  获取上月的开始时间
     * @return
     */
    public static Date getBeginDayOfLastMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 2, 1);
        return getDayStartTime(calendar.getTime());
    }

    /**
     * 获取上月的结束时间
     * @return
     */
    public static Date getEndDayOfLastMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 2, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(getNowYear(), getNowMonth() - 2, day);
        return getDayEndTime(calendar.getTime());
    }

    /**
     *  获取今年是哪一年
     * @return
     */
    public static Integer getNowYear() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return Integer.valueOf(gc.get(1));
    }

    /**
     *  获取本月是哪一月
     * @return
     */
    public static int getNowMonth() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(2) + 1;
    }

    /**
     * 明天0点
     * @return
     */
    public static int getTomorrowBegin() {
        return getTimesMorning() + TimeConstant.SECONDS_PER_DAY;
    }

    /**
     * 明天24点
     * @return
     */
    public static int getTomorrowEnd() {
        return getTimesNight() + TimeConstant.SECONDS_PER_DAY;
    }

    /**
     * 下周一0点
     * @return
     */
    public static int getNextWeekBegin() {
        return getTimesWeekMorning() + TimeConstant.SECONDS_PER_WEEK;
    }

    /**
     * 下周日24点
     * @return
     */
    public static int getNextWeekEnd() {
        return getTimesWeekNight() + TimeConstant.SECONDS_PER_WEEK;
    }

    /**
     * 下月初0点
     * @return
     */
    public static long getNextMonthBegin() {
        LocalDateTime localDateTime = LocalDate.now().with(TemporalAdjusters.firstDayOfNextMonth()).atTime(0,0,0,0);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    /**
     * 下月末24点
     * @return
     */
    public static long getNextMonthEnd() {
        LocalDateTime localDateTime = LocalDate.now().plusMonths(1).with(TemporalAdjusters.lastDayOfMonth()).atTime(23,59,59,999999999);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() + 1;
    }

    /**
     * 当前季度第一天0点
     * @return
     */
    public static long getThisQuarterBegin() {
        LocalDate localDate = LocalDate.now();
        int firstMonthOfQuarter = localDate.getMonth().firstMonthOfQuarter().getValue();
        LocalDateTime localDateTime = localDate.withMonth(firstMonthOfQuarter).with(TemporalAdjusters.firstDayOfMonth()).atTime(0,0,0,0);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    /**
     * 当前季度最后一天24点
     * @return
     */
    public static long getThisQuarterEnd() {
        LocalDate localDate = LocalDate.now();
        int lastMonthOfQuarter = localDate.getMonth().firstMonthOfQuarter().plus(2).getValue();
        LocalDateTime localDateTime = localDate.withMonth(lastMonthOfQuarter).with(TemporalAdjusters.lastDayOfMonth()).atTime(23,59,59,999999999);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() + 1;
    }

    /**
     * 上个季度第一天0点
     * @return
     */
    public static long getLastQuarterBegin() {
        LocalDate localDate = LocalDate.now();
        int firstMonthOfQuarter = localDate.getMonth().firstMonthOfQuarter().getValue();
        LocalDateTime localDateTime = localDate.withMonth(firstMonthOfQuarter).minusMonths(3).with(TemporalAdjusters.firstDayOfMonth()).atTime(0,0,0,0);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    /**
     * 上个季度最后一天24点
     * @return
     */
    public static long getLastQuarterEnd() {
        LocalDate localDate = LocalDate.now();
        int lastMonthOfQuarter = localDate.getMonth().firstMonthOfQuarter().plus(2).getValue();
        LocalDateTime localDateTime = localDate.withMonth(lastMonthOfQuarter).minusMonths(3).with(TemporalAdjusters.lastDayOfMonth()).atTime(23,59,59,999999999);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() + 1;
    }

    /**
     * 下个季度第一天0点
     * @return
     */
    public static long getNextQuarterBegin() {
        LocalDate localDate = LocalDate.now();
        int firstMonthOfQuarter = localDate.getMonth().firstMonthOfQuarter().getValue();
        LocalDateTime localDateTime = localDate.withMonth(firstMonthOfQuarter).plusMonths(3).with(TemporalAdjusters.firstDayOfMonth()).atTime(0,0,0,0);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    /**
     * 下个季度最后一天24点
     * @return
     */
    public static long getNextQuarterEnd() {
        LocalDate localDate = LocalDate.now();
        int lastMonthOfQuarter = localDate.getMonth().firstMonthOfQuarter().plus(2).getValue();
        LocalDateTime localDateTime = localDate.withMonth(lastMonthOfQuarter).plusMonths(3).with(TemporalAdjusters.lastDayOfMonth()).atTime(23,59,59,999999999);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() + 1;
    }

    /**
     * 上半年第一天0点
     * @return
     */
    public static long getFirstHalfYearBegin() {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = localDate.withMonth(Month.JANUARY.getValue()).with(TemporalAdjusters.firstDayOfMonth()).atTime(0,0,0,0);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    /**
     * 上半年最后一天24点
     * @return
     */
    public static long getFirstHalfYearEnd() {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = localDate.withMonth(Month.JUNE.getValue()).with(TemporalAdjusters.lastDayOfMonth()).atTime(23,59,59,999999999);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() + 1;
    }

    /**
     * 下半年第一天0点
     * @return
     */
    public static long getSecondHalfYearBegin() {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = localDate.withMonth(Month.JULY.getValue()).with(TemporalAdjusters.firstDayOfMonth()).atTime(0,0,0,0);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    /**
     * 下半年最后一天24点
     * @return
     */
    public static long getSecondHalfYearEnd() {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = localDate.withMonth(Month.DECEMBER.getValue()).with(TemporalAdjusters.lastDayOfMonth()).atTime(23,59,59,999999999);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() + 1;
    }

    /**
     * 今年第一天0点
     * @return
     */
    public static long getThisYearBegin() {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = localDate.with(TemporalAdjusters.firstDayOfYear()).atTime(0,0,0,0);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    /**
     * 今年最后一天24点
     * @return
     */
    public static long getThisYearEnd() {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = localDate.with(TemporalAdjusters.lastDayOfYear()).atTime(23,59,59,999999999);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() + 1;
    }

    /**
     * 去年第一天0点
     * @return
     */
    public static long getLastYearBegin() {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = localDate.minusYears(1).with(TemporalAdjusters.firstDayOfYear()).atTime(0,0,0,0);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    /**
     * 去年最后一天24点
     * @return
     */
    public static long getLastYearEnd() {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = localDate.minusYears(1).with(TemporalAdjusters.lastDayOfYear()).atTime(23,59,59,999999999);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() + 1;
    }

    /**
     * 明年第一天0点
     * @return
     */
    public static long getNextYearBegin() {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = localDate.with(TemporalAdjusters.firstDayOfNextYear()).atTime(0,0,0,0);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    /**
     * 明年最后一天24点
     * @return
     */
    public static long getNextYearEnd() {
        LocalDate localDate = LocalDate.now();
        LocalDateTime localDateTime = localDate.plusYears(1).with(TemporalAdjusters.lastDayOfYear()).atTime(23,59,59,999999999);
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() + 1;
    }

    public static void main(String[] args) {
        System.out.println(DateTimeUtil.getStringEpochSecond((long) GetTimeInMillisUtil.getTomorrowBegin(), DateTimeUtil.SDF));
        System.out.println(DateTimeUtil.getStringEpochSecond((long) GetTimeInMillisUtil.getTomorrowEnd(), DateTimeUtil.SDF));
        System.out.println("--------------------------------------------------------------------------------------------------");
        System.out.println(DateTimeUtil.getStringEpochSecond((long) GetTimeInMillisUtil.getNextWeekBegin(), DateTimeUtil.SDF));
        System.out.println(DateTimeUtil.getStringEpochSecond((long) GetTimeInMillisUtil.getNextWeekEnd(), DateTimeUtil.SDF));
        System.out.println("--------------------------------------------------------------------------------------------------");
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getNextMonthBegin(), DateTimeUtil.SDF));
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getNextMonthEnd(), DateTimeUtil.SDF));
        System.out.println("--------------------------------------------------------------------------------------------------");
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getThisQuarterBegin(), DateTimeUtil.SDF));
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getThisQuarterEnd(), DateTimeUtil.SDF));
        System.out.println("--------------------------------------------------------------------------------------------------");
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getLastQuarterBegin(), DateTimeUtil.SDF));
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getLastQuarterEnd(), DateTimeUtil.SDF));
        System.out.println("--------------------------------------------------------------------------------------------------");
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getNextQuarterBegin(), DateTimeUtil.SDF));
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getNextQuarterEnd(), DateTimeUtil.SDF));
        System.out.println("--------------------------------------------------------------------------------------------------");
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getFirstHalfYearBegin(), DateTimeUtil.SDF));
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getFirstHalfYearEnd(), DateTimeUtil.SDF));
        System.out.println("--------------------------------------------------------------------------------------------------");
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getSecondHalfYearBegin(), DateTimeUtil.SDF));
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getSecondHalfYearEnd(), DateTimeUtil.SDF));
        System.out.println("--------------------------------------------------------------------------------------------------");
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getThisYearBegin(), DateTimeUtil.SDF));
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getThisYearEnd(), DateTimeUtil.SDF));
        System.out.println("--------------------------------------------------------------------------------------------------");
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getLastYearBegin(), DateTimeUtil.SDF));
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getLastYearEnd(), DateTimeUtil.SDF));
        System.out.println("--------------------------------------------------------------------------------------------------");
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getNextYearBegin(), DateTimeUtil.SDF));
        System.out.println(DateTimeUtil.getStringEpochSecond(GetTimeInMillisUtil.getNextYearEnd(), DateTimeUtil.SDF));
    }
}
